import {parseTime} from '@/common/util'
import iconv from 'iconv-lite'
import Bmp from 'binary-bmp'

// #ifdef MP-WEIXIN
const fs = uni.getFileSystemManager();
// #endif
const config = {
  api: {
    bind: 'https://open.memobird.cn/home/setuserbind',
    print: 'https://open.memobird.cn/home/printpaper',
    watch: 'https://open.memobird.cn/home/getprintstatus',
    image: 'https://open.memobird.cn/home/getSignalBase64Pic',
    url: 'https://open.memobird.cn/home/printpaperFromUrl',
    html: 'https://open.memobird.cn/home/printpaperFromHtml',
  }
}

class Memobird {
  static async sleep(time) {
    return new Promise(resolve => setTimeout(resolve, time))
  }

  // Memobird Required Text Format
  static formatText(base64) {
    return `T:${base64}`
  }

  // Memobird Required Picture Format
  static formatImage(base64) {
    return `P:${base64}`
  }

  constructor(options = {}) {
    this.ak = options.ak
    this.memobirdID = options.memobirdID
    this.useridentifying = options.useridentifying
  }

  get timestamp() {
    return parseTime(+new Date)
  }

  // api请求
  post(type, data) {
    return new Promise((resolve, reject) => {
      uni.request({
        url: config.api[type],
        method: 'POST',
        // header: {
        //   'content-type': 'application/x-www-form-urlencoded'
        // },
        data: Object.assign({
          ak: this.ak,
          timestamp: this.timestamp,
          memobirdID: this.memobirdID,
        }, data),
        success: response => {
          const {showapi_res_code, showapi_res_error} = response.data
          if (showapi_res_code !== 1) {
            reject({showapi_res_code, showapi_res_error})
          } else {
            resolve(response.data)
          }
        }
      })
    })
  }

  // 账号关联
  // user bind
  async init() {
    if (this.inited) return false
    const {showapi_userid} = await this.post('bind', {useridentifying: this.useridentifying})
    this.userID = showapi_userid
    this.inited = true
  }

  // 获取纸条打印状态
  // get print status
  async getPrintStatus(printcontentid) {
    const {printflag} = await this.post('watch', {printcontentid})
    return printflag
  }

  // 延时一定时间后获取咕咕机打印状态
  // get print status after a while
  async glance(printcontentid, delay = 1000) {
    await Memobird.sleep(delay)
    const printflag = await this.getPrintStatus(printcontentid)
    return printflag
  }

  // 监听打印状态
  // keep getting print status until printed or timeout
  async watch(printcontentid, delay = 3000, maxDelay = 15000) {
    let printflag = 0
    let totalDelay = 0
    while (printflag !== 1 && totalDelay < maxDelay) {
      await Memobird.sleep(delay)
      printflag = await this.getPrintStatus(printcontentid)
      totalDelay += delay
    }
    return printflag
  }

  // 纸条打印
  // print paper
  async print(...items) {
    // 参数不仅可以是字符串，还可以是未完成的encode操作生成的promise
    // items can be not only base64 text data,
    // but also promise that will return a base64 text data
    const printcontents = []
    for (const item of items) {
      if (typeof item.then === 'function') {
        printcontents.push(await item)
      } else {
        printcontents.push(item)
      }
    }
    const printcontent = printcontents.join('|')
    const {printcontentid} = await this.post('print', {userID: this.userID, printcontent})
    return printcontentid
  }

  // 打印文字
  async printText(text) {
    const printcontentid = await this.print(this.encodeText(text))
    return printcontentid
  }

  encodeText(text) {
    return Memobird.formatText(iconv.encode(`${text}\n`, 'gbk').toString('base64'))
  }

  // 打印 Canvas
  async printCanvas(canvas) {
    const printcontentid = await this.print(this.encodeCanvas(canvas))
    return printcontentid
  }

  encodeCanvas(canvas) {
    const binary = new Bmp(Bmp.BINARY, canvas)
    return Memobird.formatImage(binary.getBase64(true))
  }

  // 打印图片
  async printImage(image, width) {
    const printcontentid = await this.print(await this.encodeImage(image, width))
    return printcontentid
  }

  // convert jpeg or png image into signal color bmp image through Memobird's api
  async remoteImageConversion(imgBase64String) {
    const {result} = await this.post('image', {imgBase64String})
    return result
  }

  async encodeImage(image, width) {
    // return width ? this.encodeImageLocally(image, width) : this.encodeImageRemotely(image);
    return await this.encodeImageRemotely(image)
  }

  // use Memobird's api to convert image format
  async encodeImageRemotely(image) {
    let base64Data
    if (/^data:image\/\w+;base64,/.test(image)) {
      // image is a jpeg or png format picture's base64 data
      base64Data = image.replace(/^data:image\/\w+;base64,/, '')
    } else {
      base64Data = fs.readFileSync(image, 'base64')
    }
    const signalColorBmpBase64Data = await this.remoteImageConversion(base64Data)
    return Memobird.formatImage(signalColorBmpBase64Data)
  }

  async printUrl(printUrl) {
    const {printcontentid} = await this.post('url', {userID: this.userID, printUrl})
    return printcontentid
  }

  async printHtml(printHtmlString) {
    const printHtml = iconv.encode(printHtmlString, 'gbk').toString('base64')
    const {printcontentid} = await this.post('html', {userID: this.userID, printHtml})
    return printcontentid
  }
}

export default Memobird